﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
public class CsharpCallLua : MonoBehaviour
{

    LuaEnv luaenv;
    void Start()
    {
        luaenv = new LuaEnv();
        luaenv.DoString("require 'CsharpCallLua'");
        CallLuaFuaction();
        CallLuaFuactionMulReturn();
        CallLuaFunctionByLuaFunction();
    }

    //调用lua中的变量
    void CallLuaValue()
    {
        //获取全局变量
        string name = luaenv.Global.Get<string>("name");
        int age = luaenv.Global.Get<int>("age");
        Debug.LogFormat("{0}:{1}", name, age.ToString());

        //通过类映射lua 中的table,较耗性能,值拷贝,改变值互不影响
        Person person = luaenv.Global.Get<Person>("person");
        print("lua中table映射到类" + person.name + ":" + person.sex);
        person.name = "freedom1";
        luaenv.DoString("print(person.name)");

        //通过接口映射lua中的table,引用，会改动原来的lua数据
        Iperson iperson = luaenv.Global.Get<Iperson>("person");
        Debug.LogFormat("lua中table映射到接口，{0}：{1}", iperson.name, iperson.sex);
        iperson.name = "freedom2";
        luaenv.DoString("print(person.name)");
        iperson.work(3, 3);

        //通过字典，队列映射。
        Dictionary<string, object> dict = luaenv.Global.Get<Dictionary<string, object>>("person");
        foreach (var item in dict)
        {
            Debug.LogFormat("lua中table映射到字典{0}：{1}", item.Key, item.Value);
        }

        List<object> list = luaenv.Global.Get<List<object>>("person");
        Debug.Log("队列数量" + list.Count);
        for (int i = 0; i < list.Count; i++)
        {
            Debug.Log("lua中table映射到队列" + list[i]);
        }
    }

    //调用Lua中的function，映射到委托中，委托需要添加特性[CSharpCallLua]
    void CallLuaFuaction()
    {
        Add add = luaenv.Global.Get<Add>("add");
        add(1, 2);
        add = null;//释放前需要置空委托实例
    }

    //若方法有多个返回值，用out 或 ref
    void CallLuaFuactionMulReturn()
    {
        int num1, num2;
        MulAdd mulAdd = luaenv.Global.Get<MulAdd>("MulAdd");
        int res= mulAdd(1, 2, out num1,out num2);
        Debug.LogFormat("结果={0}，num1={1},num2={2}",res ,num1,num2);
    }

    //调用lua中的function方法二，映射到LuaFunction。效率较低，不推荐使用
    void CallLuaFunctionByLuaFunction()
    {
        print("通过LuaFunction映射lua中全局方法");
        LuaFunction luaFun = luaenv.Global.Get<LuaFunction>("MulAdd");
        object[] obs= luaFun.Call(1,2);
        for (int i = 0; i < obs.Length; i++)
        {
            print(obs[i]);
        }
    }


    private void OnDestroy()
    {
        luaenv.Dispose();
    }
}
[CSharpCallLua]
interface Iperson
{
    string name { get; set; }
    string sex { get; set; }
    void work(int a, int b);
}
class Person
{
    public string name;
    public string sex;
}

[CSharpCallLua]
delegate void Add(int a, int b);



[CSharpCallLua]
delegate int MulAdd(int a, int b,out int c,out int d);


